package com.vains.io;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.handler.inter.IReadHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Slf4j
public class ExcelUtils {

    private ExcelUtils () {}

    /**
     * Excel导入
     * @param path 文件路径
     * @param clazz 导入后映射的对象类型
     * @param headRow 表头行
     * @param <T> 泛型
     * @return 返回Excel内容
     */
    public static <T> List<T> readExcel(String path, Class<T> clazz, int headRow) {
        Assert.notNull(path, "读取文件的路径不能为空!");
        if (path.toLowerCase().endsWith(".xls")) {
            return read2003(path, clazz, headRow);
        } else if (path.toLowerCase().endsWith(".xlsx")) {
            return read2007(path, clazz, headRow);
        }
        return Collections.emptyList();
    }

    /**
     * 读取Excel 2003
     * @param path 文件路径
     * @param clazz 读取数据将会映射到这个类中,  同时也是返回集合的泛型
     * @param headRow 标题行 有几行写几
     * @param <T> 泛型
     * @return 返回读取的结果
     */
    private static <T> List<T> read2003(String path, Class<T> clazz, int headRow) {
        Assert.notNull(path, "读取文件的路径不能为空!");
        Assert.notNull(clazz, "类 Class 不能为空");
        File file = new File(path);
        Assert.isTrue(file.exists(), "文件不存在!");
        //处理上传文件
        ImportParams params = new ImportParams();
        params.setHeadRows(headRow);
        params.setConcurrentTask(true);
        return ExcelImportUtil.importExcel(file, clazz, params);
    }

    /**
     * 读取Excel 2003
     * @param path 文件路径
     * @param clazz 读取数据将会映射到这个类中,  同时也是返回集合的泛型
     * @param headRow 标题行 有几行写几
     * @param <T> 泛型
     * @return 返回读取的结果
     */
    private static <T> List<T> read2007(String path, Class<T> clazz, int headRow) {
        Assert.notNull(path, "读取文件的路径不能为空!");
        File file = new File(path);
        Assert.notNull(clazz, "类 Class 不能为空");
        Assert.isTrue(file.exists(), "文件不存在!");
        ImportParams params = new ImportParams();
        params.setHeadRows(headRow);
        long begin = System.currentTimeMillis();
        List<T> data = new ArrayList<>();
        try (InputStream fis = new FileInputStream(file)) {
            ExcelImportUtil.importExcelBySax(fis, clazz, params, new IReadHandler<T>() {
                @Override
                public void handler(T o) {
                    data.add(o);
                }

                @Override
                public void doAfterAll() {
                    System.out.println(System.currentTimeMillis() - begin);
                    log.info("文件读取完成, 耗时: {}ms", System.currentTimeMillis() - begin);
                }
            });
        } catch (FileNotFoundException e) {
            log.error("要读取的文件不存在", e);
            throw new RuntimeException("要读取的文件不存在!");
        } catch (IOException e) {
            log.error("读取文件失败", e);
            throw new RuntimeException("读取文件失败!");
        }
        return data;
    }

}
